var Router = require('@koa/router');
const service = require('../service')
var fs = require('fs');
var path = require('path');
const _ = require('lodash');
const basename = path.basename(__filename)
const {snakecase, spinalcase} = require('stringcase');

var nest = {} // 嵌套路由

let rootRoutes = []

function eachMethod(obj, fn){
	Object.getOwnPropertyNames(obj.__proto__).forEach((item)=>{
		if(item!=='constructor'){
			if(obj[item] instanceof Function){
				fn(item, obj[item])
			}
		}
	})
}

function bindRouter(fName, rPath){

	let Controller = require(path.join(__dirname, rPath.join('/'), fName))
	let controller = new Controller()
	let rName = fName.replace('.js','')
	let theRouter = new Router();

	eachMethod(controller, function(method, handle){
		let params = controller.params[method] || []
		if(theRouter[method]){
			let bindPath = "/"
			if(params.length!=0){
				bindPath += ":"
				bindPath += params.join("/:")
			}
			// 注册路由
			theRouter[method](bindPath, (ctx, next)=>{
				controller.ctx = ctx
				controller[method](ctx, next)
			})
			.all(bindPath, (ctx, next)=>{
				ctx.status = 405
			})
		}else if(['_before'].indexOf(method)==-1){
			let m_handle = method
			if(controller[m_handle].method){
				bindPath = '/' + method
				if(params.length!=0){
					bindPath += ":"
					bindPath += params.join("/:")
				}
				method = controller[m_handle].method
			}else{
				let methodFn = snakecase(m_handle)
				methodFn = methodFn.split('_')
				method = methodFn[0]
				let len = method.length
				bindPath = '/' + spinalcase(m_handle.substring(len))
				if(params.length!=0){
					bindPath += ":"
					bindPath += params.join("/:")
				}
			}
			// 注册路由
			theRouter[method](bindPath, (ctx, next)=>{
				ctx.permission.push(method)
				controller.ctx = ctx
				controller[m_handle](ctx, next)
			})
		}
	})

	nestToRoot(rName, rPath, theRouter, controller)
}
/*
* 如果最末级的分层有了，那就可以判定往上都有了,
* 判定并保证
*/
function nestToRoot(name, rPath, child, controller){
	let rName = name
	if(name=='index'){
		rName=rPath.pop()
	}
	let thePath = `/${rPath.join("/")}`
	let theRouter = nest[thePath]
	if(!theRouter){
		theRouter = new Router()
		nest[thePath] = theRouter
	}
	//嵌套
	let nName = rName.replace('_', '/:')
	if(name=='index'){
		if(controller._before){
			theRouter.use(`/${nName}`, async (ctx,next)=>{
				await controller._before(ctx, next)
			})
		}
	}
	theRouter.use(`/${nName}`, child.routes(), child.allowedMethods({throw: true}))

	if(rPath.length==0){//到顶层了
		rootRoutes.push(theRouter)
	}else{
		let len = rPath.length
		let pPath = rPath.slice(0, len-1)
		nestToRoot(_.last(rPath), pPath, theRouter)
	}
}

function readDir(dir, pPath = []) {
  const files = fs.readdirSync(dir)

  let index = files.indexOf('index.js')
  if(index!=-1){
	let tem = files[0]
	files[0] = files[index]
	files[index] = tem
  }
	

  files.filter(file => {
	let fileNot = (file !== basename) && (file!=='base.js') && (file!=='init.js')
    return (file.indexOf('.') !== 0) &&  (file.slice(-3) === '.js' && fileNot) || file.indexOf('.') === -1
  })
  .forEach((item, index) => {
	let tPath = _.clone(pPath)
    var fullPath = path.join(dir, item)
    const stat = fs.statSync(fullPath)
    if (stat.isDirectory()) {
	   if(item=="lib")return //排除库
	   tPath.push(item)
       readDir(path.join(dir, item), tPath); //递归读取文件
    } else { 
	   bindRouter(item, tPath)
    }    
  })
}
readDir(__dirname)


module.exports = rootRoutes
